use crate::redis_pool;
use deadpool_redis::redis::{cmd, pipe};

/// 模糊匹配关键字的KEYS
///
/// # 参数
/// - `pattern` - 配置关键字
///
/// # 返回值
/// - `anyhow::Result<Vec<String>>`
/// - `Vec<String>` - 匹配上的KEY集合
///
/// # 注意
/// - 如果查询所有值需要传入参数 `*`
pub async fn keys(pattern: &str) -> anyhow::Result<Vec<String>> {
    let mut conn = redis_pool::get().await?;
    let keys: Vec<String> = cmd("KEYS").arg(&[pattern]).query_async(&mut conn).await?;
    tracing::info!("Redis keys: {:?}", keys);
    Ok(keys)
}

/// 设置String类型的键值对
///
/// # 参数
/// - `key` - key
/// - `value` - key对应的value值
pub async fn set_string(key: &str, value: &str) -> anyhow::Result<()> {
    let mut conn = redis_pool::get().await?;
    cmd("SET").arg(&[key, value]).query_async::<()>(&mut conn).await?;
    tracing::info!("Set string success: {}:{}", key, value);
    Ok(())
}

/// 设置String类型的键值对含过期时间
///
/// # 参数
/// - `key` - key
/// - `value` - key对应的value值
/// - `expire` - 过期时间 秒
pub async fn set_string_expire(key: &str, value: &str, expire: i64) -> anyhow::Result<()> {
    let mut conn = redis_pool::get().await?;
    pipe()
        .cmd("SET").arg(&[key, value])
        .cmd("EXPIRE").arg(key).arg(expire)
        .query_async::<()>(&mut conn).await?;
    Ok(())
}

/// 获取string类型的value值
///
/// # 参数
/// - `key`
pub async fn get_string(key: &str) -> anyhow::Result<String> {
    let mut conn = redis_pool::get().await?;
    let value: String = cmd("GET").arg(&[key]).query_async(&mut conn).await?;
    Ok(value)
}

/// 设置hash
pub async fn set_hash(key: &str, field: &str, value: &str) -> anyhow::Result<()> {
    let mut conn = redis_pool::get().await?;
    cmd("HSET").arg(key).arg(&[field, value]).query_async::<()>(&mut conn).await?;
    Ok(())
}

/// 设置HASH数据含过期时间
pub async fn set_hash_expire(key: &str, field: &str, value: &str, expire: i64) -> anyhow::Result<()> {
    let mut conn = redis_pool::get().await?;
    pipe().cmd("HSET").arg(key).arg(field).arg(value)
        .cmd("EXPIRE").arg(key).arg(expire).query_async::<()>(&mut conn).await?;
    Ok(())
}
/// 获取HASH的filed值value
pub async fn get_hash(key: &str, field: &str) -> anyhow::Result<String> {
    let mut conn = redis_pool::get().await?;
    let value: String = cmd("HGET").arg(key).arg(field).query_async(&mut conn).await?;
    Ok(value)
}

/// Set集合设置值
pub async fn set_set(key: &str, value: &str) -> anyhow::Result<()> {
    let mut conn = redis_pool::get().await?;
    cmd("SADD").arg(&[key, value]).query_async::<()>(&mut conn).await?;
    Ok(())
}

/// 获取Set集合所有的value值
pub async fn get_set_all(key: &str) -> anyhow::Result<Vec<String>> {
    let mut conn = redis_pool::get().await?;
    let values: Vec<String> = cmd("SMEMBERS").arg(key).query_async::<Vec<String>>(&mut conn).await?;
    Ok(values)
}